package com.example.springbooteasycode.utils.qrcode.withText;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import jakarta.servlet.http.HttpServletResponse;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.util.List;

public class QRCodeUtil {

    public static BufferedImage createBackground(int width, int height) {
        BufferedImage backgroundImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = backgroundImage.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.WHITE);
        g2d.fill(new RoundRectangle2D.Float(0, 0, width, height, 10f, 10f));
        g2d.dispose();
        return backgroundImage;
    }

    public static BufferedImage generateQRCode(String data, int width, int height) throws WriterException, IOException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        BitMatrix bitMatrix = qrCodeWriter.encode(data, BarcodeFormat.QR_CODE, width, height, hints);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "PNG", stream);
        byte[] bytes = stream.toByteArray();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        return ImageIO.read(bais);
    }

    public static void addTextToBackground(Graphics2D g2d, String text, Color color, int fontSize, int yPosition) {
        g2d.setColor(color);
        g2d.setFont(new Font("Arial", Font.BOLD, fontSize));
        g2d.drawString(text, 50, yPosition);
    }

    public static void saveImage(HttpServletResponse response, BufferedImage image) throws IOException {
        // 设置响应类型为PNG图片
        response.setContentType("image/png");
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);

        // 将图像写入响应流
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", baos);
        baos.flush();
        baos.writeTo(response.getOutputStream());
        baos.close();
    }

    public static byte[] generateQRCodeImage(String url, String number, String name, String location, int qrWidth, int qrHeight, int backgroundWidth, int backgroundHeight) throws IOException, WriterException {
        // 创建背景图像
        BufferedImage backgroundImage = createBackground(backgroundWidth, backgroundHeight);

        // 在背景上生成二维码
        BufferedImage qrCodeImage = generateQRCode(url, qrWidth, qrHeight);

        // 计算二维码在背景上的位置
        int xPosition = (backgroundWidth - qrWidth) / 2;
        int yPosition = 10; // 将二维码放置在背景的顶部

        // 将二维码放在背景的中心
        Graphics2D g2d = backgroundImage.createGraphics();
        g2d.drawImage(qrCodeImage, xPosition, yPosition, null);

        // 添加文本信息
        addTextToBackground(g2d, "编号: " + number, Color.BLACK, 15, 230);
        addTextToBackground(g2d, "名称: " + name, Color.BLACK, 15, 250);
        addTextToBackground(g2d, "位置: " + location, Color.BLACK, 15, 270);

        g2d.dispose();

        // 将图像转换为字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(backgroundImage, "png", baos);
        baos.flush();
        byte[] imageBytes = baos.toByteArray();
        baos.close();
        return imageBytes;
    }

    public static void saveImagesAsZip(HttpServletResponse response, List<byte[]> images, List<String> filenames) throws IOException {
        // 设置响应类型为ZIP文件
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=qr_codes.zip");

        ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
        for (int i = 0; i < images.size(); i++) {
            byte[] imageData = images.get(i);
            String filename = filenames.get(i);
            ZipEntry zipEntry = new ZipEntry(filename);
            zos.putNextEntry(zipEntry);
            zos.write(imageData);
            zos.closeEntry();
        }
        zos.finish();
        zos.close();
    }

}
